package cc.rengu.igas.share.core.realize.impl;

import cc.rengu.igas.bomp.facade.base.Header;
import cc.rengu.igas.bomp.facade.bean.EmvParamInfoBean;
import cc.rengu.igas.bomp.facade.bean.MarketingAdsInfoBean;
import cc.rengu.igas.bomp.facade.request.*;
import cc.rengu.igas.bomp.facade.response.*;
import cc.rengu.igas.bomp.facade.result.Result;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.ShareServiceConstant;
import cc.rengu.igas.share.core.model.*;
import cc.rengu.igas.share.core.realize.BompService;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.utility.util.*;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by wangcheng on 2021/6/25 14:02
 */
public class BompServiceImpl implements BompService {
    private final RgLogger rglog = RgLog.getLogger(this.getClass().getName());
    private String callMode = "1";

    public BompServiceImpl() throws Exception {
        String callMode = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.APPLICATION_CONF_NODE, AppConfigConstant.BOMP_SERVICE_CALL_MODE);
        if (!StringUtil.isEmptyOrNull(callMode)) {
            if (!"0".equals(callMode.trim()) && !"1".equals(callMode.trim())) {
                rglog.error("内管相关信息获取调用模式<{}>参数配置错误:0-本地调用，1-微服务调用!", callMode.trim());
                throw new BizException("内管相关信息获取方式配置有误:<{}>", callMode);
            } else {
                this.callMode = callMode.trim();
            }
        }
    }

    @Override
    public BankCodeInfo getBankCodeInfoByBandBranchCode(String bankBranchCode) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        rglog.info("正在获取机构号<{}>的联行行号信息,信息获取方式为<{}>", bankBranchCode, "0".equals(callMode) ? "本地调用" : "微服务调用");
        Header header = new Header();
        header.setInstId(instId);
        header.setSrcSysId(ChannelEnum.BOMP.getChannelType());
        header.setChanlId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.HEADER_SRC_SYS_ID));
        header.setTxnNum("M00BM051");
        header.setBizType("00");
        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        header.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        header.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        BankNameCodeQueryRequest bankNameCodeQueryRequest = new BankNameCodeQueryRequest();
        bankNameCodeQueryRequest.setHeader(header);
        bankNameCodeQueryRequest.setBankCode(bankBranchCode);
        bankNameCodeQueryRequest.setPageSize(-1);
        bankNameCodeQueryRequest.setPageIndex(-1);
        Result<BankNameCodeQueryResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if ("0".equals(callMode)) {
            Class clasz = Class.forName(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE_INNER_PATH);
            callResult = (Result<BankNameCodeQueryResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.BOMP_BANK_NAME_CODE_QUERY_METHOD, bankNameCodeQueryRequest);
        } else {
            callResult = (Result<BankNameCodeQueryResponse>) dubboService.callDubboService(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE, ShareServiceConstant.BOMP_BANK_NAME_CODE_QUERY_METHOD, bankNameCodeQueryRequest);
        }
        if (null == callResult || null == callResult.getResult() || null == callResult.getResult().getBankNameCodeInfoBeanList()) {
            rglog.info("根据人行联行行号查询联行行号信息失败,bankBranchCode:<{}>", bankBranchCode);
            return null;
        }
        BankCodeInfo bankCodeInfo = new BankCodeInfo();
        BeanUtil.beanCopy(callResult.getResult().getBankNameCodeInfoBeanList().get(0), bankCodeInfo);
        return bankCodeInfo;
    }

    @Override
    public BankCodeInfo getBankCodeInfoByCupsInstId(String cupsInstId, String villageBankId) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        rglog.info("正在获取银联机构号<{}>及村镇银行标识<{}>的联行行号信息,信息获取方式为<{}>", cupsInstId, villageBankId, "0".equals(callMode) ? "本地调用" : "微服务调用");
        Header header = new Header();
        header.setInstId(instId);
        header.setSrcSysId(ChannelEnum.BOMP.getChannelType());
        header.setChanlId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.HEADER_SRC_SYS_ID));
        header.setTxnNum("M00BM051");
        header.setBizType("00");
        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        header.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        header.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        BankNameCodeQueryRequest bankNameCodeQueryRequest = new BankNameCodeQueryRequest();
        bankNameCodeQueryRequest.setHeader(header);
        if (StringUtil.isEmptyOrNull(villageBankId) || "1".equals(villageBankId)) {
            bankNameCodeQueryRequest.setCupsInstId(cupsInstId);
        } else {
            bankNameCodeQueryRequest.setCupsInstId(cupsInstId + "|" + villageBankId);
        }
        Result<BankNameCodeQueryResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if ("0".equals(callMode)) {
            Class clasz = Class.forName(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE_INNER_PATH);
            callResult = (Result<BankNameCodeQueryResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.BOMP_BANK_NAME_CODE_QUERY_METHOD, bankNameCodeQueryRequest);
        } else {
            callResult = (Result<BankNameCodeQueryResponse>) dubboService.callDubboService(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE, ShareServiceConstant.BOMP_BANK_NAME_CODE_QUERY_METHOD, bankNameCodeQueryRequest);
        }
        if (null == callResult || null == callResult.getResult() || null == callResult.getResult().getBankNameCodeInfoBeanList()) {
            rglog.info("根据银联机构号查询联行行号信息失败,cupsInstId:<{}>,villageBankId:<{}>", cupsInstId, villageBankId);
            return null;
        }
        BankCodeInfo bankCodeInfo = new BankCodeInfo();
        BeanUtil.beanCopy(callResult.getResult().getBankNameCodeInfoBeanList().get(0), bankCodeInfo);
        return bankCodeInfo;
    }

    @Override
    public List<MarketingAdsInfo> getMarketingAdsInfo(String instId, String adType) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        rglog.info("正在获取营销广告信息,信息获取方式为<{}>", "0".equals(callMode) ? "本地调用" : "微服务调用");
        Header header = new Header();
        header.setInstId(instId);
        header.setSrcSysId(ChannelEnum.BOMP.getChannelType());
        header.setChanlId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.HEADER_SRC_SYS_ID));
        header.setTxnNum("M00BM044");
        header.setBizType("00");
        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        header.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        header.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        MarketingAdsInfoQueryRequest marketingAdsInfoQueryRequest = new MarketingAdsInfoQueryRequest();
        marketingAdsInfoQueryRequest.setHeader(header);
        marketingAdsInfoQueryRequest.setUserId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.USER_ID));
        marketingAdsInfoQueryRequest.setAdType(adType);
        Result<MarketingAdsInfoQueryResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if ("0".equals(callMode)) {
            Class clasz = Class.forName(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE_INNER_PATH);
            callResult = (Result<MarketingAdsInfoQueryResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.BOMP_MARKETING_ADS_INFO_QUERY_METHOD, marketingAdsInfoQueryRequest);
        } else {
            callResult = (Result<MarketingAdsInfoQueryResponse>) dubboService.callDubboService(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE, ShareServiceConstant.BOMP_MARKETING_ADS_INFO_QUERY_METHOD, marketingAdsInfoQueryRequest);
        }
        if (null == callResult || null == callResult.getResult() || null == callResult.getResult().getMarketingAdsInfoBeanList()) {
            rglog.info("根据营销广告类型查询营销广告信息失败,instId:<{}>,adType:<{}>", instId, adType);
            return null;
        }
        List<MarketingAdsInfo> marketingAdsInfoList = new ArrayList<>();
        for (MarketingAdsInfoBean marketingAdsInfoBean : callResult.getResult().getMarketingAdsInfoBeanList()) {
            MarketingAdsInfo marketingAdsInfo = new MarketingAdsInfo();
            BeanUtil.beanCopy(marketingAdsInfoBean, marketingAdsInfo);
            marketingAdsInfoList.add(marketingAdsInfo);
        }
        return marketingAdsInfoList;
    }

    @Override
    public OrgInfo getOrgInfo(String instId, String orgType, String orgCode) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        rglog.info("正在获取机构类型为<{}>,机构号为<{}>的机构信息,信息获取方式为<{}>", orgType, orgCode, "0".equals(callMode) ? "本地调用" : "微服务调用");
        Header header = new Header();
        header.setInstId(instId);
        header.setSrcSysId(ChannelEnum.BOMP.getChannelType());
        header.setChanlId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.HEADER_SRC_SYS_ID));
        header.setTxnNum("M00BM020");
        header.setBizType("00");
        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        header.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        header.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        OrgInfoListQueryRequest orgInfoListQueryRequest = new OrgInfoListQueryRequest();
        orgInfoListQueryRequest.setHeader(header);
        orgInfoListQueryRequest.setOrgType(orgType);
        orgInfoListQueryRequest.setOrgCode(orgCode);
        orgInfoListQueryRequest.setPageIndex(-1);
        orgInfoListQueryRequest.setPageSize(-1);
        Result<OrgInfoListQueryResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if ("0".equals(callMode)) {
            Class clasz = Class.forName(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE_INNER_PATH);
            callResult = (Result<OrgInfoListQueryResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.BOMP_ORG_INFO_LIST_QUERY_METHOD, orgInfoListQueryRequest);
        } else {
            callResult = (Result<OrgInfoListQueryResponse>) dubboService.callDubboService(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE, ShareServiceConstant.BOMP_ORG_INFO_LIST_QUERY_METHOD, orgInfoListQueryRequest);
        }
        if (null == callResult || null == callResult.getResult() || null == callResult.getResult().getOrgInfoList()) {
            rglog.info("根据机构号查询机构信息失败,instId:<{}>,orgType:<{}>,orgCode:<{}>", instId, orgType, orgCode);
            return null;
        }
        rglog.debug("查询到的机构信息：{}", JSON.toJSONString(callResult.getResult().getOrgInfoList()));
        OrgInfo orgInfo = new OrgInfo();
        BeanUtil.beanCopy(callResult.getResult().getOrgInfoList().get(0), orgInfo);
        return orgInfo;
    }

    @Override
    public QrCodeInfo getQrCodeInfo(String instId, String qrUrl, String qrCode) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        rglog.info("正在获取二维码信息,信息获取方式为<{}>", "0".equals(callMode) ? "本地调用" : "微服务调用");
        Header header = new Header();
        header.setInstId(instId);
        header.setSrcSysId(ChannelEnum.BOMP.getChannelType());
        header.setChanlId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.HEADER_SRC_SYS_ID));
        header.setTxnNum("T00BM011");
        header.setBizType("00");
        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        header.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        header.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        MchntQrCodeQueryRequest mchntQrCodeQueryRequest = new MchntQrCodeQueryRequest();
        mchntQrCodeQueryRequest.setHeader(header);
        mchntQrCodeQueryRequest.setQrUrl(qrUrl);
        mchntQrCodeQueryRequest.setQrCode(qrCode);
        mchntQrCodeQueryRequest.setPageIndex(-1);
        mchntQrCodeQueryRequest.setPageSize(-1);
        Result<MchntQrCodeQueryResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if ("0".equals(callMode)) {
            Class clasz = Class.forName(ShareServiceConstant.BOMP_QRCODE_MANAGE_SERVICE_INNER_PATH);
            callResult = (Result<MchntQrCodeQueryResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.BOMP_QRCODE_QUERY_METHOD, mchntQrCodeQueryRequest);
        } else {
            callResult = (Result<MchntQrCodeQueryResponse>) dubboService.callDubboService(ShareServiceConstant.BOMP_QRCODE_MANAGE_SERVICE, ShareServiceConstant.BOMP_QRCODE_QUERY_METHOD, mchntQrCodeQueryRequest);
        }
        if (null == callResult || null == callResult.getResult() || null == callResult.getResult().getQrCodeInfoList()) {
            rglog.info("根据二维码URL或者二维码code信息失败,instId:<{}>,qrUrl:<{}>,qrCode:<{}>", instId, qrUrl, qrCode);
            return null;
        }
        rglog.debug("查询到的二维码信息：{}", JSON.toJSONString(callResult.getResult().getQrCodeInfoList()));
        QrCodeInfo qrCodeInfo = new QrCodeInfo();
        BeanUtil.beanCopy(callResult.getResult().getQrCodeInfoList().get(0), qrCodeInfo);
        return qrCodeInfo;
    }

    @Override
    public List<EmvParamInfo> getEmvParamInfo(String instId) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        rglog.info("正在获取EMV参数配置信息,信息获取方式为<{}>", "0".equals(callMode) ? "本地调用" : "微服务调用");
        Header header = new Header();
        header.setInstId(instId);
        header.setSrcSysId(ChannelEnum.BOMP.getChannelType());
        header.setChanlId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.HEADER_SRC_SYS_ID));
        header.setTxnNum("M00BM060");
        header.setBizType("00");
        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        header.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        header.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        EmvParamInfoQueryRequest emvParamInfoQueryRequest = new EmvParamInfoQueryRequest();
        emvParamInfoQueryRequest.setHeader(header);
        Result<EmvParamInfoQueryResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if ("0".equals(callMode)) {
            Class clasz = Class.forName(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE_INNER_PATH);
            callResult = (Result<EmvParamInfoQueryResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.BOMP_EMV_PARAM_INFO_QUERY_METHOD, emvParamInfoQueryRequest);
        } else {
            callResult = (Result<EmvParamInfoQueryResponse>) dubboService.callDubboService(ShareServiceConstant.BOMP_PUBLIC_QUERY_SERVICE, ShareServiceConstant.BOMP_EMV_PARAM_INFO_QUERY_METHOD, emvParamInfoQueryRequest);
        }
        if (null == callResult || null == callResult.getResult() || null == callResult.getResult().getEmvParamInfoList()) {
            rglog.info("获取EMV参数信息失败,instId:<{}>", instId);
            return null;
        }
        List<EmvParamInfo> emvParamInfoList = new ArrayList<>();
        for (EmvParamInfoBean emvParamInfoBean : callResult.getResult().getEmvParamInfoList()) {
            EmvParamInfo emvParamInfo = new EmvParamInfo();
            BeanUtil.beanCopy(emvParamInfoBean, emvParamInfo);
            emvParamInfoList.add(emvParamInfo);
        }
        return emvParamInfoList;
    }

    @Override
    public MchntBaseInfo getMchntBaseInfoByMchntNo(String mchntNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        rglog.info("正在获取商户号<{}>的商户基本信息,信息获取方式为<{}>", mchntNo, "0".equals(callMode) ? "本地调用" : "微服务调用");
        Header header = new Header();
        header.setInstId(instId);
        header.setSrcSysId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.HEADER_SRC_SYS_ID));
        header.setChanlId(ChannelEnum.UPMP.getChannelType());
        header.setTxnNum("M00BM067");
        header.setBizType("00");
//        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        header.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        header.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        MchntBaseInfoQueryRequest mchntBaseInfoQueryRequest = new MchntBaseInfoQueryRequest();
        mchntBaseInfoQueryRequest.setHeader(header);
        if (!StringUtil.isEmptyOrNull(mchntNo)) {
            mchntBaseInfoQueryRequest.setMchntNo(mchntNo);
        }
        Result<MchntBaseQueryResponse> callResult = null;
        DubboService dubboService = new DubboServiceImpl();
        if ("0".equals(callMode)) {
            Class clasz = Class.forName(ShareServiceConstant.BOMP_MCHNT_QUERY_SERVICE_INNER_PATH);
            callResult = (Result<MchntBaseQueryResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.BOMP_MCHNT_BASE_QUERY_METHOD, mchntBaseInfoQueryRequest);
        }else {
            callResult = (Result<MchntBaseQueryResponse>) dubboService.callDubboService(ShareServiceConstant.BOMP_MCHNT_QUERY_SERVICE, ShareServiceConstant.BOMP_MCHNT_BASE_QUERY_METHOD, mchntBaseInfoQueryRequest);
        }
        if (null == callResult || null == callResult.getResult() || null == callResult.getResult().getMchntBaseInfo()) {
            rglog.info("根据商户号查询商户基本信息失败,mchntNo:<{}>", mchntNo);
            return null;
        }
        MchntBaseInfo mchntBaseInfo = new MchntBaseInfo();
        BeanUtil.beanCopy(callResult.getResult().getMchntBaseInfo(), mchntBaseInfo);
        return mchntBaseInfo;
    }
}
